package com.yhd.utils;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.MessageDigest;
import java.security.Security;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class WeixinCommonUtil {
    /**
     *
     */
    public static String WX_APPID = "wx5626d3e6d94b2342";
    public static String WX_APPSECRET = "f62d20dccd7f99e9abd2a23f35d22202";


    public static String decrypt(String encryptedData, String iv, String sessionKey) throws Exception{
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] keyByte = decoder.decode(sessionKey);
        byte[] encryptedDataByte = decoder.decode(encryptedData);
        byte[] ivByte = decoder.decode(iv);

//这边导入 bouncycastle Maven包
/*
    <dependency>
     <groupId>org.bouncycastle</groupId>
     <artifactId>bcprov-ext-jdk16</artifactId>
     <version>1.46</version>
     <type>jar</type>
     <scope>compile</scope>
    </dependency>
*/
        if (Security.getProvider("BC") == null) {
            Security.addProvider(new BouncyCastleProvider());
        }
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");
        SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
        AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
        parameters.init(new IvParameterSpec(ivByte));
        //设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE, spec,parameters);

        byte[] resultByte = cipher.doFinal(encryptedDataByte);

        String result = null;
        if (null != resultByte && resultByte.length > 0) {
            result = new String(resultByte, "UTF-8");
        }
// 返回前，可以对比appId
        return result;
    }
    /**
     * 小程序获取openid等相关参数
     * @param appId
     * @param appSecret
     * @param code
     * @return
     */
    public static String getAuthByCode(String appId,String appSecret,String code) {
        System.out.println("appId = "+ appId + "appSecret = " + appSecret + "code = " + code);
        String url = "https://api.weixin.qq.com/sns/jscode2session";
        Map<String,String> map = new HashMap<>();
        map.put("appid",appId);
        map.put("secret", appSecret);
        map.put("js_code", code);
        map.put("grant_type", "authorization_code");
        String body = HttpClient.sendGet(url, map);
        System.out.println("return data  body = " + body);
        return body;
    }

    public static String getAccessToken(String appId, String appSecret) {
        System.out.println("appId = "+ appId + "appSecret = " + appSecret);
        String url = "https://api.weixin.qq.com/cgi-bin/token";
        Map<String,String> map = new HashMap<>();
        map.put("appid",appId);
        map.put("secret", appSecret);
        map.put("grant_type", "client_credential");
        String body = HttpClient.sendGet(url, map);
        System.out.println("return data  body = " + body);
        return body;
    }

    public static String getTicket(String fAccessToken) {
        System.out.println("fAccessToken = "+ fAccessToken);
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
        Map<String,String> map = new HashMap<>();
        map.put("access_token", fAccessToken);
        map.put("type", "jsapi");
        String body = HttpClient.sendGet(url, map);
        System.out.println("return data  body = " + body);
        return body;
    }

    /*public static String getShowInfo(String fTicket, String fShowUrl) {
        String keyWord = null;
        try {
            keyWord = URLDecoder.decode(fShowUrl, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        System.out.println("fTicket = "+ fTicket + "fShowUrl = " + keyWord);
        SortedMap<String,String> map = new TreeMap<String,String>();
        String fNonceStr = RandomUtil.generateString(16);;
        String fTimeStr = null;
        try {
            fTimeStr = DateUtil.getCurrentUnixTime() + "";
        } catch (Exception e) {
            e.printStackTrace();
        }
        map.put("jsapi_ticket", fTicket);
        map.put("noncestr", fNonceStr);
        map.put("timestamp", fTimeStr);
        map.put("url", keyWord);
        System.out.println("微信分享信息前：" + map.toString());
        System.out.println("微信分享信息1：" + encodeSign(map));
        String fSignature = encode(encodeSign(map));
        Map<String,String> mapInfo = new HashMap<>();
        mapInfo.put("appId", WX_APPID);
        mapInfo.put("timestamp", fTimeStr);
        mapInfo.put("nonceStr", fNonceStr);
        mapInfo.put("signature", fSignature);
        System.out.println("微信分享信息：" + mapInfo.toString());
        return mapInfo.toString();
    }
*/
    private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    private static String getFormattedText(byte[] bytes) {
        int len = bytes.length;
        StringBuilder buf = new StringBuilder(len * 2);
        // 把密文转换成十六进制的字符串形式
        for (int j = 0; j < len; j++) {
            buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
            buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
        }
        return buf.toString();
    }

    public static String encode(String str) {
        if (str == null) {
            return null;
        }
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
            messageDigest.update(str.getBytes());
            return getFormattedText(messageDigest.digest());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * sign 签名 （参数名按ASCII码从小到大排序（字典序）+key+MD5+转大写签名）
     * @param map
     * @return
     */
   /* public static String encodeSign(SortedMap<String,String> map){
        Set<Map.Entry<String, String>> entries = map.entrySet();
        Iterator<Map.Entry<String, String>> iterator = entries.iterator();
        List<String> values = Lists.newArrayList();

        while(iterator.hasNext()){
            Map.Entry entry = (Map.Entry) iterator.next();
            String k = String.valueOf(entry.getKey());
            String v = String.valueOf(entry.getValue());
            if (StringUtils.isNotEmpty(v) && entry.getValue() !=null) {
                values.add(k + "=" + v);
            }
        }
        String sign = StringUtils.join(values, "&");
        return sign;
    }*/

    /*public static void main(String[] args) {
        Map<String,String> map = new HashMap<>();
        String fNonceStr = RandomUtil.generateString(16);
        String fTimeStr = null;
        try {
            fTimeStr = DateUtil.getCurrentUnixTime() + "";
        } catch (Exception e) {
            e.printStackTrace();
        }
        map.put("jsapi_ticket", "jsapi_ticket");
        map.put("noncestr", fNonceStr);
        map.put("timestamp", fTimeStr);
        map.put("url", "url");
        SortedMap<String,String> sortedMap = new TreeMap<String,String>();
        sortedMap.put("jsapi_ticket", "jsapi_ticket");
        sortedMap.put("noncestr", fNonceStr);
        sortedMap.put("timestamp", fTimeStr);
        sortedMap.put("url", "url");

        System.out.println("待签名字符串:" + encodeSign(sortedMap));

    }*/
}
